﻿// By Conmajia<conmajia@gmail.com> on September 6th., 2012
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using WeifenLuo.WinFormsUI.Docking;

namespace CSharpGo
{
    public partial class FormWaterGame : DockContent
    {
        public FormWaterGame()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }

        Game game = new Game();

        int stepCount = 0;

        Bottle current;
        Bottle source;
        Bottle dest;

        Random rand = new Random();
        Stopwatch watch = new Stopwatch();

        private void button1_Click(object sender, EventArgs e)
        {
            //OpenFileDialog ofd = new OpenFileDialog();
            //ofd.Filter = "Drop Water Game Level(*.gam)|*.gam";
            //if (ofd.ShowDialog() == DialogResult.OK)
            //{
            //    game.Load(ofd.FileName);
            //    game.World.Bounds = this.ClientRectangle;
            //}
            game.AutoGenerate(3);
            game.World.Bounds = this.ClientRectangle;

            // start timing
            watch.Reset();
            watch.Start();

            Refresh();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            if (game.Target < 0)
                return;

            foreach (Bottle b in game.World.Bottles)
            {
                g.DrawImageUnscaled(
                    b.Draw(),
                    b.Bounds.Location
                    );

                if (current != null)
                {
                    g.DrawRectangle(Pens.Gold, current.Bounds);
                }
            }

            // game description
            g.DrawString(
                string.Format("在 {1} 升的瓶子里倒入 {0} 升水。\n步数: {2}\n用时: {3} 秒",
                game.Amount,
                game.World.Bottles[game.Target].Capacity,
                stepCount,
                watch.ElapsedMilliseconds / 1000
                ),
                SystemFonts.CaptionFont,
                Brushes.Gold,
                5,
                5
                );
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (game.World == null)
                return;

            foreach (Bottle b in game.World.Bottles)
            {
                if (b.Bounds.Contains(e.Location))
                {
                    current = b;

                    if (source != null && current != source)
                    {
                        dest = current;
                    }
                    else
                    {
                        dest = null;
                    }

                    Invalidate();

                    break;
                }
                else
                {
                    current = null;
                }
            }
        }

        protected override void OnMouseDoubleClick(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                if (current != null)
                {
                    current.DropOut();
                }

            if (e.Button == MouseButtons.Right)
                if (current != null)
                {
                    current.DropIn();
                }
            stepCount++;
            Refresh();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                if (source != null)
                {
                    // selected and clicked on nothing
                    if (dest == null)
                    {
                        // cancelled
                        source = null;
                    }
                    else
                    {
                        // valid target                    

                        Invalidate(dest.Bounds);
                    }
                    Cursor.Current = Cursors.Default;
                }
                else
                {
                    if (current != null && current.Content > 0)
                    {
                        source = current;
                        Cursor.Current = new Cursor(current.Draw().GetHicon());
                    }
                }
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (dest != null)
            {
                if (dest.FreeSpace > 0)
                {
                    if (source.Content >= dest.FreeSpace)
                    {
                        source.DropOut(dest.FreeSpace);
                        dest.DropIn(dest.FreeSpace);
                    }
                    else
                    {
                        dest.DropIn(source.Content);
                        source.DropOut();
                        // clear cursor
                        Cursor.Current = Cursors.Default;

                    }
                    stepCount++;
                }

                Refresh();

                if (game.CheckSuccess())
                {
                    // stop timing
                    watch.Stop();

                    MessageBox.Show("Succeed in " + stepCount + " steps.\n用时 " + watch.ElapsedMilliseconds / 1000 + " 秒");
                    stepCount = 0;

                    button1_Click(null, null);
                }
            }
            dest = source = null;
        }

        protected override void OnResize(EventArgs e)
        {
            if (this.ClientRectangle != Rectangle.Empty)
            {
                game.World.Bounds = this.ClientRectangle;
                Refresh();
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Refresh();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}
